package com.jxm.graph;

import com.jxm.linear.Queue;

/**
 * @Author: jxm
 * @Description: 有向图API设计
 * @Date: 2022/8/2 22:12
 * @Version: 1.0
 */
public class Digraph {

    //记录顶点数量
    private final int V;
    //记录边数量
    private int E;
    //邻接表
    private Queue<Integer>[] adj;

    //创建一个包含V个顶点但不包含边的有向图
    public Digraph(int V){
        //初始化顶点数量
        this.V = V;
        //初始化录边数量
        this.E = 0;
        //初始化邻接表(索引是每个顶点，值是存邻接表Queue对象)
        this.adj = new Queue[V];
        for (int i = 0; i < adj.length; i++) {
            adj[i] = new Queue<Integer>();
        }
    }

    /**
     * 获取图中顶点的数量
     * @return
     */
    public int V(){
        return V;
    }

    /**
     * 获取图中边的数量
     * @return
     */
    public int E(){
        return E;
    }

    /**
     * 向有向图中添加一条边 v->w
     * @param v
     * @param w
     */
    public void addEdge(int v,int w){
        //只需要让顶点w出现在顶点v的邻接表中，
        // 因为边是有向的，最终，顶点v的邻接表存储的相邻顶点的含义是：v->其他顶点
        adj[v].enqueue(w);
        //边数量+1
        E++;
    }

    /**
     * 获取由v指出的边所连接的所有顶点
     * @param v
     * @return
     */
    public Queue<Integer> adj(int v){
        return adj[v];
    }

    /**
     * 该图的反向图
     * @return
     */
    private Digraph reverse(){
        //创建有向图对象
        Digraph r = new Digraph(V);

        for (int v=0;v<V;v++){
            //获取由该顶点v指出的所有边
            for (Integer w : adj[v]) { //原图中表示的是由顶点v->w的边
                r.addEdge(w,v);
            }
        }


        return r;
    }
}
